package org.zero.db;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @author Zero
 */
public class TransactionProxy implements InvocationHandler {

    private final Object target;

    public TransactionProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
        Object result = null;

        // 如果是修改方法（增删改）设置数据库连接并进行事务管理
        if (ServiceMethodHelper.isChangeMethod(method)) {
            try {
                // 设置连接
                ConnectionUtil.setTransactionManager();
                // 开始事务
                TransactionManager.begin();
                // 执行业务方法
                result = method.invoke(target, args);
                // 提交事务
                TransactionManager.commit();
            } catch (Exception e) {
                // 回滚事务
                TransactionManager.rollback();
                // 抛出原始异常
                throwCause(e);
            } finally {
                // 移除连接
                ConnectionUtil.removeTransactionManager();
            }
            // 如果是查询方法（查）只设置数据库连接
        } else if (ServiceMethodHelper.isQueryMethod(method)) {
            try {
                ConnectionUtil.setTransactionManager();
                result = method.invoke(target, args);
            } catch (Exception e) {
                throwCause(e);
            } finally {
                ConnectionUtil.removeTransactionManager();
            }
            // 其它方法只执行
        } else {
            try {
                result = method.invoke(target, args);
            } catch (Exception e) {
                throwCause(e);
            }
        }

        return result;
    }

    public void throwCause(Exception e) {
        Throwable cause = e.getCause();
        if (Objects.isNull(cause)) {
            throw new RuntimeException(e);
        }
        throw new RuntimeException(cause);
    }
}
